<?php
declare (strict_types = 1);

namespace app\index\model;

use app\common\model\content\Article as ArticleModel;
use app\common\model\content\ArticleTag;
use think\model\Relation;

/**
 * @mixin think\Model
 */
class Article extends ArticleModel
{
    const LIMIT_NUM = 15;


    /**
     * #基础查询构造器
     */
    public static function baseQuery(){
        return static::where('status','=', static::STATUS_PUB);
    }

    /**
     * #获取首页精品推荐
     * @param int $num
     * @return \think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getBests(int $num = 5){
        $cacheKey = json_encode(array_merge(['best_articles'],(array)$num));
        if(!$best = cache($cacheKey)){
            $best = static::baseQuery()
                ->cache(24 * 3600)
                ->where(['best'=> static::BEST_YES])
                ->order(['id'=>'desc','create_time'=>'desc'])
                ->limit($num)
                ->field(['id','title','brief','image'])
                ->select();

            cache($cacheKey, $best, 24 * 3600);
        }
        return $best;

    }


    /**
     * #获取查询构造器
     * @param array $where
     * @return Article
     */
    private static function getQuery(array $where){
        return static::baseQuery()
            ->field(['id','title','brief','image','best','liked','visited','commented','user_id','topic_id','category_id','create_time'])
            ->where($where);
    }

    /**
     * #获取当前查询总数目
     * @param array $where
     * @return int
     */
    public static function getCount(array $where = []){
        return static::getQuery($where)->count();
    }

    /**
     * #获取文章分页列表
     * @param null $page
     * @param null $limit
     * @param array $where
     * @return array
     * @throws \think\db\exception\DbException
     */
    public static function getList($page=null, $limit=null, array $where=[]){
        return static::getQuery($where)
            ->with(['user','topic','category'])
            ->order('id', 'desc')
            ->paginate([
                'list_rows' => empty($limit) || $limit < 1 || $limit > 15 ? static::LIMIT_NUM : $limit,
                'page'      => empty($page) || $page <= 0 ? 1 : $page,
            ])->each(function($item, $key){
                $item->imageUrl = (string) $item->imageUrl;
                $item->articleUrl = (string) url('article/read',['id'=>$item->id]);
                $item->authorUrl = (string) url('user/read',['id'=>$item->user_id]);
                $item->categoryUrl = (string) url('category/read',['category_id'=>$item->category_id]);
                $item->topicUrl = empty($item->topic_id) ? '' : (string) url('topic/read',['id'=>$item->topic_id]);
                $item->absoluteTime = absoluteTime($item->create_time);
            })->toArray();
    }


    /**
     * #按标签查询列表
     * 关联中间表(只为查询tag_id)
     * @return \think\model\relation\BelongsTo
     */
    public function at()
    {
        return $this->belongsTo(ArticleTag::class,'id', 'article_id');
    }


    /**
     * #获取查询指定标签的文章列表查询构造器
     * @param int $tag_id
     * @return Article
     */
    private static function getQueryByTag(int $tag_id){
        return static::baseQuery()
            ->field(['id','title','brief','image','best','liked','visited','commented','user_id','topic_id','category_id','create_time'])
            ->withJoin(['at'=>function(Relation $query){
                $query->withField(['article_id','tag_id']);
            }],'right')
            ->where('at.tag_id','=', $tag_id);
    }

    /**
     * #关联指定标签的文章数目
     * @param int $tag_id
     * @return int
     */
    public static function getCountByTag(int $tag_id){
        return static::getQueryByTag($tag_id)->count();
    }

    /**
     * #根据标签获取文章列表
     * @param null $page
     * @param null $limit
     * @param int $tag_id
     * @return array
     * @throws \think\db\exception\DbException
     */
    public static function getListByTag(int $page,int $limit, int $tag_id){
        return static::getQueryByTag($tag_id)
            ->with(['user','topic','category'])
            ->order('id', 'desc')
            ->paginate([
                'list_rows' => empty($limit) || $limit < 1 || $limit > 15 ? static::LIMIT_NUM : $limit,
                'page'      => empty($page) || $page <= 0 ? 1 : $page,
            ])->each(function($item, $key){
                $item->imageUrl = (string) $item->imageUrl;
                $item->articleUrl = (string) url('article/read',['id'=>$item->id]);
                $item->authorUrl = (string) url('user/read',['id'=>$item->user_id]);
                $item->categoryUrl = (string) url('category/read',['category_id'=>$item->category_id]);
                $item->topicUrl = empty($item->topic_id) ? '' : (string) url('topic/read',['id'=>$item->topic_id]);
                $item->absoluteTime = absoluteTime($item->create_time);
            })->toArray();
    }


    /**
     * #获取当前热门文章总数目(只查询3个月之内的文章)
     * @return int
     */
    public static function getHotCount(){
        return static::getQuery([
            ['create_time', '>', strtotime('-3 month')]
        ])->count();
    }


    /**
     * #获取热门文章分页列表
     * @param null $page
     * @param null $limit
     * @return array
     * @throws \think\db\exception\DbException
     */
    public static function getHotList($page=null, $limit=null){
        return static::getQuery([
            ['create_time', '>', strtotime('-3 month')]
        ])
            ->with(['user','topic','category'])
            ->order('visited', 'desc')
            ->paginate([
                'list_rows' => empty($limit) || $limit < 1 || $limit > 15 ? static::LIMIT_NUM : $limit,
                'page'      => empty($page) || $page <= 0 ? 1 : $page,
            ])->each(function($item, $key){
                $item->imageUrl = (string)$item->imageUrl;
                $item->articleUrl = (string) url('article/read',['id'=>$item->id]);
                $item->authorUrl = (string) url('user/read',['id'=>$item->user_id]);
                $item->categoryUrl = (string) url('category/read',['category_id'=>$item->category_id]);
                $item->topicUrl = empty($item->topic_id) ? '' : (string) url('topic/read',['id'=>$item->topic_id]);
                $item->absoluteTime = absoluteTime($item->create_time);
            })->toArray();
    }





    /**
     * #查询话题文章的上一页下一页
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getPrevNext(){
        if ((int) $this->topic_id <= 0 ) return [];

        //上一页
        $prev = static::baseQuery()
            ->where('topic_id', '=', $this->topic_id)
            ->order('id','DESC')
            ->where('id', '<', $this->id)
            ->limit(1)
            ->field(['id', 'title'])
            ->find();

        $next = static::baseQuery()
            ->where('topic_id', '=', $this->topic_id)
            ->order('id','ASC')
            ->where('id','>', $this->id)
            ->limit(1)
            ->field(['id', 'title'])
            ->find();

        return [
            'prev' => [
                'url' => $prev ? (string)url('article/read', ['id'=>$prev['id']]) :'javascript:;',
                'title' => $prev ? $prev['title'] : '已经是第一页了.'
            ],
            'next' => [
                'url' => $next ? (string)url('article/read', ['id'=>$next['id']]) : 'javascript:;',
                'title' => $next ? $next['title'] : '已经是最后一页了.'
            ],
        ];

    }






}
